/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sucursal;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import sucursal.*;
import org.jdom.input.*;
import org.jdom.output.*;
import org.jdom.*;
import java.util.Iterator;
import java.util.List;
/**
 *
 * @author User
 */
public class Transaccion extends Thread {

    int portEscucha;
    int portSalida;
    String nombre;
    int tiempo;
    int idSucursal;
    Paquete paquete;
    boolean central;
    


    public Transaccion(int portEscucha, int portSalida, String nombre,int tiempo,int idSucursal,boolean central) {
        this.portEscucha = portEscucha;
        this.portSalida = portSalida;
        this.nombre = nombre;
        this.tiempo = tiempo;
        this.idSucursal = idSucursal;
        this.central = central;
    }


    public int getIdSucursal() {
        return idSucursal;
    }

    public void setIdSucursal(int idSucursal) {
        this.idSucursal = idSucursal;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public int getPortEscucha() {
        return portEscucha;
    }

    public void setPortEscucha(int portEscucha) {
        this.portEscucha = portEscucha;
    }

    public int getPortSalida() {
        return portSalida;
    }

    public void setPortSalida(int portSalida) {
        this.portSalida = portSalida;
    }

    public int getTiempo() {
        return tiempo;
    }

    public void setTiempo(int tiempo) {
        this.tiempo = tiempo;
    }


    public Transaccion() {
    }

    private String []  obtenerDatoMensaje(String mensaje)
    {
         String [] respuesta = new String[30];
         respuesta = mensaje.split("%");
         return respuesta;
    }

     private String []  obtenerDatoMensajeCamion(String mensaje)
    {
         String [] mensaje1 = mensaje.split("&");
         String [] respuesta = mensaje1[0].split("%");
         return respuesta;
    }
//CAMBIAR A PRIVATE
    public void decodificarPaquete(String mensaje)
    {
      String [] datoMensaje= obtenerDatoMensaje(mensaje);
      int tipo = Integer.parseInt(datoMensaje[0]);
       switch (tipo)
       {
       case 0:
           //System.out.println(mensaje);
           System.out.println("antes: " + Sucursal.getPortSalidaH() + " " + Sucursal.getPortSalidaA() );
           Sucursal.setPortSalidaH(Integer.parseInt(datoMensaje[2]));
           Sucursal.setPortSalidaA(Integer.parseInt(datoMensaje[3]));
           System.out.println("modificado: " + Sucursal.getPortSalidaH() + " " + Sucursal.getPortSalidaA() );
 //*********************ACA cambio puerto en el hilo :)******************************************************************************
           Sucursal.getHiloEscuchaH().imprimir();//para ver puerto antes
           Sucursal.getHiloEscuchaA().imprimir();
           System.out.println("id sucursal:" + datoMensaje[1]);
           Sucursal.setIdSucursal(Integer.parseInt(datoMensaje[1]));
           Sucursal.getHiloEscuchaH().setPortSalida(Integer.parseInt(datoMensaje[2]));
           Sucursal.getHiloEscuchaA().setPortSalida(Integer.parseInt(datoMensaje[3]));
           //cont = cont+1;
           Sucursal.getHiloEscuchaH().imprimir();;//para ver puerto despues
           Sucursal.getHiloEscuchaA().imprimir();;
           /*if (cont==3){
               Sucursal.getHiloEscuchaH().enviarMensaje("1%Mensaje horario");
               Sucursal.getHiloEscuchaA().enviarMensaje("1%Mensaje anti-horario");
           }*/

          break;
       case 1:
            //    4%id_sucursal%destino1%origen1%mensaje1%idPaquete&
               String[] mensajeCamion = obtenerDatoMensajeCamion(mensaje);
               String mensajeAgregar = mensajeCamion[2] + "%" + mensajeCamion[3] + "%" + mensajeCamion[4] + "%" + mensajeCamion[5];
               Sucursal.getPaquetesEnviar().add(mensajeAgregar);
               System.out.println(Sucursal.getPaquetesEnviar());
          break;
       case 2:
          //recepcionPaquete();
           break;
       case 3:
          //recibir lista sucursal
           String[] id = new String[datoMensaje.length-1];
           String[] idSucursales = new String[datoMensaje.length-1];
           for (int i =1; i<=id.length ; i++){
                idSucursales[i-1] = datoMensaje[i];
           }
           Sucursal.setIdSucursales(idSucursales);
           break;
       case 4:
          
               break;
       default:
               System.out.println("ha ocurrido un error");
       }
    }

    private void esperarMensaje() {
     try {
            ServerSocket servicio = new ServerSocket(this.portEscucha); //Puerto de escucha, donde llegan las peticiones
            Socket socketServicio = null;
           // System.out.println("Estoy escuchando para mensajes  soy nodo nº "+this.nombre);
//          System.out.println("Puerto Escucha "+this.portEscucha+" Salida"+this.portSalida);
            boolean prueba = true;
            while(prueba) {
            socketServicio = servicio.accept(); //acepta la peticion
            //Inicializa variables de recepcion y emision del msj
            PrintWriter salida = new PrintWriter(socketServicio.getOutputStream(), true);
            BufferedReader entrada = new BufferedReader(new InputStreamReader(socketServicio.getInputStream()));
            String mensaje = entrada.readLine();
            String mensajeCentral = "1%"+Sucursal.getIdSucursal();

            String [] verificarContenido = mensaje.split("&");
            if (verificarContenido.length != 0)
                Sucursal.getHiloEscuchaC().enviarMensaje(mensajeCentral+"%"+mensaje);
            else
                Sucursal.getHiloEscuchaC().enviarMensaje(mensajeCentral + mensaje);

            if (central){
               decodificarPaquete(mensaje);
            }else{
              String respuesta = identificarPaquete(mensaje);
              if (respuesta.compareTo("&") == 0)
              {
                  Sucursal.getHiloEscuchaC().enviarMensaje("2%"+Sucursal.getIdSucursal()+respuesta);
              }
              else
              {
                Sucursal.getHiloEscuchaC().enviarMensaje("2%"+Sucursal.getIdSucursal()+"%"+respuesta);
              }
              this.sleep(this.tiempo);
              this.enviarMensaje(respuesta);
              
            }  
            salida.close();
            entrada.close();
            socketServicio.close();

            System.out.println("mensaje:" + mensaje);
            }
            servicio.close();
        }catch (IOException ex) {
                System.out.println("Algo se daño:");
                ex.printStackTrace();
        }
        catch(InterruptedException esleep){
            esleep.printStackTrace();
        }
    }

    public void enviarMensaje(String mensaje){
       try {
            // TODO code application logic here
           System.out.println("mensaje a enviar:" + mensaje);
            Socket nodoSiguiente = new Socket("localhost", this.portSalida); //Puerto por donde enviara el msj
            PrintWriter salida = new PrintWriter(nodoSiguiente.getOutputStream(), true);
            salida.write(mensaje);
            salida.close();
            nodoSiguiente.close();
        } catch (IOException ex) {
            System.out.println("Problema al enviar msj");
            ex.printStackTrace();
        }

    }

    private String  identificarPaquete(String mensaje)
    {
       String respuesta1 = "";
       String respuesta2 = "";
        //poner sleep de un segundo.
       try
       {
         this.sleep(1000);
       }

       catch(InterruptedException esleep){
            esleep.printStackTrace();
        }

        idSucursal=Sucursal.getIdSucursal();
        //System.out.println("AQui: id " + idSucursal);
        Paquete []paquete = new Paquete[2];
        paquete = Paquete.decodificarMsj(mensaje);
//        System.out.println("ID PAQUETE 1 "+paquete[0].getDestino()+" ID SUCURSAL "+idSucursal);
//        System.out.println("ID PAQUETE 2 "+paquete[1].getDestino()+" ID SUCURSAL "+idSucursal);

        if(paquete[0] != null && Integer.parseInt(paquete[0].getDestino())== idSucursal)
        {
            System.out.println("Recibi mi mensaje: "+paquete[0].getMensaje());//SE DEBE ELIMINAR DEL MSJ

        }
        if(paquete[1] != null && Integer.parseInt(paquete[1].getDestino())== idSucursal)
        {
            System.out.println("Recibi mi mensaje: "+paquete[1].getMensaje()); //SE DEBE ELIMINAR DEL MSJ
        }
        
        if(paquete[0] == null && paquete[1] == null)
        {
            System.out.println("Llego camion vacio");
            int n = Sucursal.getPaquetesEnviar().size();
           // String mensajeEnviar = "";
            if(n>0)
            {
                if(n==1)
                {
                   respuesta1 = Sucursal.getPaquetesEnviar().get(0);
                   Sucursal.getPaquetesEnviar().remove(0);
                    System.out.println("se agrego un paquete al camion");
                }
                else{
                   respuesta1 = Sucursal.getPaquetesEnviar().get(0);
                   respuesta2 = Sucursal.getPaquetesEnviar().get(1);
                   Sucursal.getPaquetesEnviar().remove(0);
                   Sucursal.getPaquetesEnviar().remove(1);
                   System.out.println("se agrego 2 paquetes al camion");
                } 
            }
            else
            {
            System.out.println("No hay paquetes para agregar al camion");
            }
        }
        if(paquete[0] != null && paquete[1] != null && Integer.parseInt(paquete[0].getDestino())!= idSucursal && Integer.parseInt(paquete[1].getDestino())!= idSucursal)
        {
            System.out.println("No hay paquetes para mi");
            respuesta1= paquete[0].getOrigen()+"%"+paquete[0].getDestino()+"%"+paquete[0].getMensaje()+"%"+paquete[0].getIdpaquete();
            respuesta2= paquete[1].getOrigen()+"%"+paquete[1].getDestino()+"%"+paquete[1].getMensaje()+"%"+paquete[1].getIdpaquete();
            
        }
        if(paquete[0] != null && paquete[1] == null && Integer.parseInt(paquete[0].getDestino())!= idSucursal)
        {
            System.out.println("hay un solo  paquete 0  y no es para mi");
            respuesta1= paquete[0].getOrigen()+"%"+paquete[0].getDestino()+"%"+paquete[0].getMensaje()+"%"+paquete[0].getIdpaquete();
            int n = Sucursal.getPaquetesEnviar().size();

            if(n>0)
            {
                respuesta2 = Sucursal.getPaquetesEnviar().get(0);
                Sucursal.getPaquetesEnviar().remove(0);
            }
            
        }
        if(paquete[1] != null && paquete[0] == null && Integer.parseInt(paquete[1].getDestino())!= idSucursal)
        {
            System.out.println("hay un solo  paquete 1  y no es para mi");
            respuesta2 =  paquete[1].getOrigen()+"%"+paquete[1].getDestino()+"%"+paquete[1].getMensaje()+"%"+paquete[1].getIdpaquete();

            int n = Sucursal.getPaquetesEnviar().size();

            if(n>0)
            {
                respuesta1 = Sucursal.getPaquetesEnviar().get(0);
                Sucursal.getPaquetesEnviar().remove(0);
            }

        }

        return(respuesta1+"&"+respuesta2);
    }

    public void cargarConfiguracionSucursal() {
          try
          {
             SAXBuilder builder = new SAXBuilder(false);
             Document doc = builder.build("src/Configuracion.xml");
             Element raiz = doc.getRootElement();//Raiz mas general (configuracion
             if(raiz!=null)
             {
                 List nodos = raiz.getChildren("nodo");
                 Iterator nodo = nodos.iterator();
                 while (nodo.hasNext())
                 {
                    Element e = (Element) nodo.next();
                    Sucursal.getSucursal();
                    Sucursal.setNombre(e.getChildText("nombre"));
                    Sucursal.setPortSalidaC(Integer.parseInt(e.getChildText("puertoServidor")));
                    Sucursal.setIpServidor(e.getChildText("ipServidor"));
                    Sucursal.setPortEscuchaC(Integer.parseInt(e.getChildText("puertoEscuchaC")));
                    Sucursal.setPortEscuchaH(Integer.parseInt(e.getChildText("puertoEscuchaH")));
                    Sucursal.setPortEscuchaA(Integer.parseInt(e.getChildText("puertoEscuchaA")));
                    Sucursal.setIpSucursal(e.getChildText("ipSucursal"));
                    Sucursal.setNumMaxPaquetes(Integer.parseInt(e.getChildText("maximoPaquetes")));
                    System.out.println("num max paquete: " + Sucursal.getNumMaxPaquetes());
                 }
             }
          } catch (Exception e) {
             e.printStackTrace();
          }
     }

    public void imprimir(){
        System.out.println("Puerto de salida: "+  this.portSalida);
    }

    @Override
    public void run(){
        while(true){
            this.esperarMensaje();
        }
    }

}
